import os
import re
import sys
import tkinter as tk
from tkinter import filedialog, ttk, messagebox
import docx
import pandas as pd
from docx import Document
import threading
import time
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.shared import Pt
import Editcontext
import config
<<<<<<< HEAD


def resource_path(relative_path):
    """ 获取可执行文件的路径 """
    # 这里设定一个固定的保存路径，例如用户的主目录下的 my_app_data 文件夹
    base_path = os.path.join(os.path.expanduser("~"), "AuditNotes_data")
    
    # 确保目录存在
    os.makedirs(base_path, exist_ok=True)

    # 返回资源的完整路径
    return os.path.join(base_path, relative_path)

# 路径
config_path = resource_path("config.py")
editcontext_path = resource_path("Editcontext.py")

=======
import Lock
>>>>>>> refs/remotes/origin/main

# 配置文件实例化
config_instance = config.Path_Config()
# 初始化锁文件路径
app_main_lock_file = config_instance.resource_path('app_main.lock')
# 锁配置实例化
lock = Lock.ProcessLock(app_main_lock_file)

class ReportEditor(tk.Tk):
    def __init__(self) -> None:
        super().__init__()
        # 绑定关闭窗口事件
        self.protocol("WM_DELETE_WINDOW", self.on_close)
        # 开启进程锁
        if lock.is_running():
            sys.exit(1)  # 如果已有实例在运行，则退出当前程序
        self.setup_ui()

    def setup_ui(self):
        self.title("单体报告编辑工具")
        self.center_window(400, 400)

        self.progress_bar = ttk.Progressbar(self, orient="horizontal", length=300, mode="determinate")
        self.progress_bar.pack(pady=20)

        self.add_buttons()

    def center_window(self, width, height):
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        x_position = (screen_width - width) // 2
        y_position = (screen_height - height) // 2
        self.geometry(f'{width}x{height}+{x_position}+{y_position}')

    def add_buttons(self):
        buttons = [
            ("1、报告内容转换为Excel", self.on_convert_word),
            ("2、编辑Excel", self.preview_excel),
            ("3、将Excel内容生成报告", self.on_update_word),
            ("4、打开成果文件报告", self.preview_doc)
        ]

        for text, command in buttons:
            button = tk.Button(self, text=text, command=command)
            button.pack(pady=20)



    # 更新至 Word 文档
    def update_to_word_thread(self):
        thread = threading.Thread(target=self.update_to_word())
        thread.start()

    # 更新至 Word 文档
    def update_to_word(self):
        self.apply_updates_to_word()
  

    # 更新至 Word 文档处理函数
    def apply_updates_to_word(self):
        # 处理逻辑
        def process():
            def go_to_word():
                def process_docx_template():
                    Template = pd.read_excel(config_instance.source_xlsx)
                    df = pd.DataFrame(Template).fillna('')
                    doc = docx.Document(config_instance.sourcedoc)
                    tables = doc.tables
                    #处理格式问题
                    def format_numbers(table):
                        title_tag = r'[一二三四五六七八九十十一十二十三十四十五]+、'
                        def set_font_and_alignment(cell):
                            # 单元格水平居右
                            cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
                            for paragraph in cell.paragraphs:
                                for run in paragraph.runs:
                                    run.font.name = 'Arial Narrow'  # 设置字体为 Arial Narrow
                                    # paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT  # 设置段落对齐方式为右对齐

                        for row in table.rows:
                            for cell in row.cells:
                                # 表格每行单元格垂直居中
                                cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                                try:
                                    if row.cells[0]=='固定资产类别':
                                        cell.text= '{:,}'.format(float(cell.text))
                                        break
                                    if row.cells[0]=='税目':
                                        cell.text='{:,.2%}'.format(float(cell.text))
                                        break
                                    # 检查表格每行单元格内是否为有小数位或者没有小数位的数字
                                    if re.search(r'[-+]?\d+(\.\d*)?', cell.text):
                                        cell.text = '{:,.2f}'.format(float(cell.text))
                                        if cell.text == '0.00':
                                            cell.text ='-'
                                        set_font_and_alignment(cell)
                                    #检查表格的值是否是‘-’
                                    elif cell.text == '-':
                                        cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.RIGHT
                                    elif re.search(r'[-+]?\d+(\.\d*)?', cell.text) is None:
                                        # 若不为数字，表格每行单元格水平居中
                                        cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER


                                except ValueError:
                                    continue

                            # 处理表中中文行大写行标粗
                            # 如果行中第一个单元格符合中文大写标题号
                            if re.findall(title_tag,row.cells[0].text):
                                for cell_ in row.cells:
                                    for paragraph in cell_.paragraphs:
                                        # 遍历段落中的每一个Run对象
                                        for run in paragraph.runs:
                                            # 将Run对象的bold属性设置为True，以使其加粗
                                            run.bold = True

                            #处理表中合计居中，合计行标粗
                            # 如果行中第一个单元格值为合计则该单元格水平居中
                            if re.match(r'合\s*计',row.cells[0].text):
                                row.cells[0].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
                                for cell_ in row.cells:
                                    for paragraph in cell_.paragraphs:
                                        # 遍历段落中的每一个Run对象
                                        for run in paragraph.runs:
                                            # 将Run对象的bold属性设置为True，以使其加粗
                                            run.bold = True

                            # 行中第一个单元格水平居左
                            else:
                                row.cells[0].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.LEFT
                        # 表格第一行第一个单元格水平居中
                        table.rows[0].cells[0].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
                        # 表格第一行第一个单元格垂直居中
                        table.rows[0].cells[0].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER

                    #核心函数
                    def replace_cell_text(table, data_sub):
                        for i, row in enumerate(table.rows):
                            for j, cell in enumerate(row.cells):
                                # 直接从处理好的 DataFrame 中获取值
                                cell.text = str(data_sub.iloc[i, j + 3])

                    # 行数调整
                    for y, table in enumerate(tables):
                        # 获取当前表对应的 DataFrame 部分
                        data_sub = df[df[0] == y].dropna(axis=1, how='all')


                        # 根据 DataFrame 的行数调整 Word 表格行数
                        required_rows = data_sub.shape[0]
                        current_rows = len(table.rows)
                        if required_rows > current_rows:
                            for _ in range(required_rows - current_rows):
                                table.add_row()
                        elif required_rows < current_rows:
                            for _ in range(current_rows - required_rows):
                                table._tbl.remove(table.rows[-1]._tr)


                        # 获取 DataFrame 中有数值的有效列数
                        _cols = data_sub.astype(bool).sum(axis=1).max() - 3
                        valid_cols = _cols
                        # 调整 Word 表格列数
                        current_cols = len(table.columns)
                        required_cols = valid_cols

                        if required_cols > current_cols:
                            for _ in range(required_cols - current_cols):
                                table.add_column(width=Pt(18))
                        elif required_cols < current_cols:
                            if current_cols > required_cols:
                                for _ in range(current_cols - required_cols):
                                    for row in table._tbl.tr_lst:
                                        del row.tc_lst[-1]  # 删除每一行的最后一个单元格

                        # 替换文本内容
                        try:
                            replace_cell_text(table, data_sub)
                
                        except IndexError:
                            # print('第%d张表可能存在问题' % (y + 1))
                            continue
                        format_numbers(table)            
                    doc.save(config_instance.target_doc) 
                try:
                    for step in range(100):
                        # 假设这里是一个逐步处理的过程，更新进度条
                        self.progress_bar["value"] = step
                        self.progress_bar.update_idletasks()
                        # 模拟处理时间
                        time.sleep(0.05)
                    process_docx_template()
                    messagebox.showinfo("处理结果", "处理完毕")
                except Exception as e:
                    messagebox.showerror("错误", f"更新至 Word 时出错: {e}")
            go_to_word()
        thread_2 = threading.Thread(target=process)
        thread_2.start()
        return thread_2    



    # WORD文件转换表格数据
    def conversion_process_thread(self, file_name):
        thread = threading.Thread(target=lambda: self.conversion_process(file_name))
        thread.start()
        
    # WORD文件转换表格数据
    def conversion_process(self, file_name):
        self.process_conversion(file_name)

    # WORD文件转换表格数据处理函数
    def process_conversion(self, file_name):
        # 转换处理逻辑
        def process():            
            def conversion_process(file_name):
                def get_text_above_table(doc, index, max_chars=20, min_chars=4):
                    previous_text = ''
                    for paragraph in reversed(doc.paragraphs):
                        if paragraph._element in doc.tables[index]._element.xpath('preceding-sibling::*'):
                            if paragraph.text == '利润表' or (min_chars < len(paragraph.text) < max_chars):
                                previous_text = paragraph.text
                                break
                    return previous_text
                try:
                    doc = Document(file_name)
                    doc.save(config_instance.sourcedoc)
                    table_data = []
                    tables = doc.tables
                    total_tables = len(tables)

                    for index, table in enumerate(tables):
                        progress = (index + 1) / total_tables * 100
                        self.progress_bar["value"] = progress
                        self.progress_bar.update_idletasks()
                        for row in table.rows:
                            cut_row_data = [re.sub(r',', '', cell.text) for cell in row.cells]
                            previous_text = get_text_above_table(doc, index)
                            cut_row_data.insert(0, previous_text)
                            cut_row_data.insert(0, str(index))
                            table_data.append(cut_row_data)
                    table_df=pd.DataFrame(table_data)     
                    if table_df is not None:
                        table_df = table_df.replace({'\u3000,': '', '[': '', ']': '', ',': ''})
                        styled_df = table_df.style.set_properties(**{'text-align': 'center'})
                        styled_df.to_excel(config_instance.source_xlsx)
                    messagebox.showinfo("处理结果", "处理完成")    
                except Exception as e:
                    messagebox.showerror("错误", f"处理文件时出错: {e}")
            conversion_process(file_name)
        thread_1 = threading.Thread(target=process)
        thread_1.start()
        return thread_1



    # 调用Editcontext模块
    def preview_excel(self):
        if not os.path.exists(config_instance.source_xlsx):
            messagebox.showerror("错误", "未找到xlsx模板文件")
        else:
            self.destroy()
            os.remove(app_main_lock_file)
            Editcontext.EditExcel()  # 切换到EditExcel界面
        # 删除锁文件    



    # 打开成果文件报告
    def preview_doc(self):
        self.open_file(config_instance.target_doc, "打开文件时出错")

    def open_file(self, file_path, error_message):
        try:
<<<<<<< HEAD
                os.startfile(file_path)
=======
            os.startfile(file_path)
>>>>>>> refs/remotes/origin/main
        except Exception:
            messagebox.showerror("错误", error_message)

    def on_close(self):
        # 程序退出时删除锁文件
        if os.path.exists(app_main_lock_file):
            os.remove(app_main_lock_file)
        sys.exit(0)

    def on_convert_word(self):
        file_name = filedialog.askopenfilename(
            parent=self,
            title="选择 Word 文件",
            filetypes=(("Word files", "*.docx"), ("all files", "*.*"))
        )
        if file_name:
            self.conversion_process_thread(file_name)

    def on_update_word(self):
        self.update_to_word_thread()

# 运行应用程序
if __name__ == "__main__":
    app = ReportEditor()
    app.mainloop()
    # 程序结束时删除锁文件
    if os.path.exists(app_main_lock_file):
        os.remove(app_main_lock_file)